Skip to content

Latest commit

 

History

History
74 lines (58 loc) · 2.83 KB

贪心算法_659分割数组为连续子序列.md

File metadata and controls

74 lines (58 loc) · 2.83 KB

给你一个按升序排序的整数数组 num(可能包含重复数字),请你将它们分割成一个或多个子序列,其中每个子序列都由连续整数组成且长度至少为 3 。

如果可以完成上述分割,则返回 true ;否则,返回 false 。

示例 1:

输入: [1,2,3,3,4,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3 3, 4, 5

示例 2:

输入: [1,2,3,3,4,4,5,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3, 4, 5 3, 4, 5

示例 3:

输入: [1,2,3,4,4,5] 输出: False

这道题可以使用贪心算法来解决。

具体地,对于数组中的每个数,都要尽可能地将它添加到已有的子序列中,如果没有合适的子序列,则新建一个子序列。

假设我们使用两个哈希表 dict1 和 dict2,其中 dict1[i] 表示数字 i 可以作为某个子序列的末尾;dict2[i] 表示数字 i 在所有子序列中还剩下的个数。初始化时,dict1 和 dict2 中的所有元素都是 0。

遍历数组中的每个数,对于当前数 i,分两种情况:

如果 i 在 dict2 中的值大于 0,说明它可以添加到某个子序列的末尾。因此,我们先检查是否存在以 i-1 结尾的子序列,即是否存在 dict1[i-1] > 0。如果存在,则将数字 i 添加到该子序列中,即将 dict1[i-1] 减 1,并将 dict1[i] 加 1,同时将 dict2[i] 减 1。如果不存在,则新建一个长度为 3 的子序列,即 dict1[i]=1,dict1[i+1]=1,dict1[i+2]=1,同时将 dict2[i] 减 1,dict2[i+1] 减 1,dict2[i+2] 减 1。

如果 i 在 dict2 中的值等于 0,说明它已经被用完了,跳过即可。

在遍历完数组之后,如果没有剩余的数字,说明可以分割成若干个子序列,返回 true;否则,返回 false。
var isPossible = function (nums) {

  let dict1 = {}; // 存储以 i 结尾的子序列的数量
  let dict2 = {}; // 存储数字 i 在所有子序列中还剩下的个数
  for (let num of nums) {
    dict2[num] = (dict2[num] || 0) + 1; // 统计数字 num 的个数
  }
  for (let num of nums) {
    if (dict2[num] == 0) {
      continue;
    }
    if (dict1[num - 1] > 0) {
      // 如果存在以 num-1 结尾的子序列,则将 num 添加到该子序列中
      dict1[num - 1] -= 1;
      dict1[num] = (dict1[num] || 0) + 1;
      dict2[num] -= 1;
    } else if (dict2[num + 1] > 0 && dict2[num + 2] > 0) {
      // 如果不存在以 num-1 结尾的子序列,则新建一个长度为 3 的子序列
      dict2[num] -= 1;
      dict2[num + 1] -= 1;
      dict2[num + 2] -= 1;
      dict1[num + 2] = (dict1[num + 2] || 0) + 1;
    } else {
      return false; // 无法将 num 添加到已有的子序列中,返回 false
    }
  }
  return true;

};

// @lc code=end